use askama::Template;
use axum::{
    extract::ConnectInfo,
    http::StatusCode,
    response::{Html, IntoResponse},
    extract::{  Json},
};
use std::path::PathBuf;
use axum_messages::{Message, Messages};

use crate::users::AuthSession;

use serde::{Deserialize, Serialize};
use std::fs::{self, File};
use std::io::Write;
use crate::download::user_init_db;
use password_auth::{generate_hash, verify_password};
use crate::logdb::write_log_async;
use sqlx::Row;
use crate::users::User;

use std::collections::HashSet;
use getifaddrs::getifaddrs;

use std::net::{IpAddr};
use axum_casbin::CasbinVals;
use axum::extract::FromRequestParts;

#[derive(Template)]
#[template(path = "admin-password-ui.html")]
struct AdminTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    password_change_result: String,
    password_result_color: String,
}

#[derive(Template)]
#[template(path = "user-password-ui.html")]
struct UserPwdTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    password_change_result: String,
    password_result_color: String,
}

#[derive(Template)]
#[template(path = "auditor-password-ui.html")]
struct AuditorPwdTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    password_change_result: String,
    password_result_color: String,
}

#[derive(Template)]
#[template(path = "user-management.html")]
struct UserManTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    current_page: i32,               // 当前页码
    total_pages: i32,                // 总页数
    total_logs: i32,                 // 总日志数
}

#[derive(Template)]
#[template(path = "admin-user-management.html")]

struct AdminManTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    current_page: i32,               // 当前页码
    total_pages: i32,                // 总页数
    total_logs: i32,                 // 总日志数
}

#[derive(Template)]
#[template(path = "system-settings.html")]
struct SysSetTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    upload_result: String,
    upload_result_color: String,
    qr_url: String,
    http_root: String,
    ip_addresses: Vec<String>,
}

#[derive(Template)]
#[template(path = "file-browser.html")]
struct FileBrowserTemplate<'a> {
    messages: Vec<Message>,
    username: &'a str,
    upload_result: String,
    upload_result_color: String,
    http_root: String,
}

pub mod get {
    use super::*;

    pub async fn admin_setting(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        match auth_session.user {
            Some(user) =>         Html(
                                        AdminTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            password_change_result: "".to_string(),
                                            password_result_color: "".to_string(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        AdminTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            password_change_result: "".to_string(),
                                            password_result_color: "".to_string(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }


    pub async fn auditor_setting(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        match auth_session.user {
            Some(user) =>         Html(
                                        AuditorPwdTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            password_change_result: "".to_string(),
                                            password_result_color: "".to_string(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        AuditorPwdTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            password_change_result: "".to_string(),
                                            password_result_color: "".to_string(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }
    pub async fn user_pwd_setting(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        match auth_session.user {
            Some(user) =>         Html(
                                        UserPwdTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            password_change_result: "".to_string(),
                                            password_result_color: "".to_string(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        UserPwdTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            password_change_result: "".to_string(),
                                            password_result_color: "".to_string(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }

    pub async fn userman_setting(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        match auth_session.user {
            Some(user) =>         Html(
                                        UserManTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            current_page: 1,               // 初始页码为1
                                            total_pages: 1,                // 初始总页数为1
                                            total_logs: 0,                 // 初始总日志数为0
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        UserManTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            current_page: 1,               // 初始页码为1
                                            total_pages: 1,                // 初始总页数为1
                                            total_logs: 0,                 // 初始总日志数为0
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }
    
    pub async fn admin_userman_setting(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        match auth_session.user {
            Some(user) =>         Html(
                                        AdminManTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            current_page: 1,               // 初始页码为1
                                            total_pages: 1,                // 初始总页数为1
                                            total_logs: 0,                 // 初始总日志数为0
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        AdminManTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            current_page: 1,               // 初始页码为1
                                            total_pages: 1,                // 初始总页数为1
                                            total_logs: 0,                 // 初始总日志数为0
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }

    pub async fn sysset_setting(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        let ip_vec: Vec<String> = get_local_ip_addresses();
        match auth_session.user {
            Some(user) =>         Html(
                                        SysSetTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            upload_result: "".to_string(),
                                            upload_result_color:"gray".to_string(),
                                            qr_url: crate::util::get_qr_url(),
                                            http_root: "".to_string(),
                                            ip_addresses: ip_vec,
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        SysSetTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            upload_result: "".to_string(),
                                            upload_result_color:"gray".to_string(),
                                            qr_url: crate::util::get_qr_url(),
                                            http_root: "".to_string(),
                                            ip_addresses: ip_vec,
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }    

    pub async fn file_browser(auth_session: AuthSession, 
                            messages: Messages, 
                            headers: axum::http::HeaderMap,
                            request: axum::extract::Request) -> impl IntoResponse {
        // 从请求中获取客户端IP
        let xff_header = headers.get("x-forwarded-for");
        let client_ip = match xff_header {
            Some(header) => header.to_str().unwrap_or("unknown"),
            None => {
                // 如果没有X-Forwarded-For头，尝试从连接中获取
                &match request.extensions().get::<std::net::SocketAddr>() {
                    Some(addr) => addr.to_string(),
                    None => "unknown".to_string(),
                }
            }
        };
        println!("client ip : {}", client_ip);
        match auth_session.user {
            Some(user) =>         Html(
                                        FileBrowserTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &user.username,
                                            upload_result: "".to_string(),
                                            upload_result_color:"gray".to_string(),
                                            http_root: crate::util::get_http_root_url(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
            None => Html(
                                        FileBrowserTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: "none",
                                            upload_result: "".to_string(),
                                            upload_result_color:"gray".to_string(),
                                            http_root: crate::util::get_http_root_url(),
                                        }
                                        .render()
                                        .unwrap(),
                                    ),
        }
    }  
    pub async fn list_users() -> Result<Json<Vec<User>>, StatusCode> {
        let db = user_init_db().await.expect("fail to init user db");
        let users: Vec<User> = sqlx::query_as("select * from users")
            .fetch_all(&db)
            .await
           .map_err(|e| {
                eprintln!("数据库错误: {}", e);
                StatusCode::INTERNAL_SERVER_ERROR
            })?;
        // 创建新 Vec，将每个用户的密码替换为 "********"
        let masked_users: Vec<User> = users
            .into_iter()
            .map(|mut user| {
                user.password = "********".to_string();
                user
            })
            .collect();

        Ok(Json(masked_users))
    }
}
// 定义配置结构
#[derive(Debug, Serialize, Deserialize)]
pub struct QRConfig {
    qr_code_url: String, //字段名要与前端一致。
}

pub mod post {
    use axum::Extension;
    use sqlx::SqlitePool;

    use crate::util::{save_http_root_url_to_config, HttpRootConfig};

    use super::*;
    // Handle POST requests to /saveqr

    // Handle POST requests to /saveqr
    pub async fn saveqr(auth_session: AuthSession, 
                            messages: Messages, 
                            axum::Form(body): axum::Form<QRConfig>) -> impl IntoResponse {
        // Validate URL
        println!("save qr {}", body.qr_code_url);
        let url = body.qr_code_url.clone();
        if url.trim().is_empty() {
            return Err(StatusCode::BAD_REQUEST);
        }

        // 保存 URL 到 config.toml
        match save_qr_code_url_to_config(&url) {
            Ok(_) => Ok(Html(
                                        SysSetTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &auth_session.user.unwrap().username,
                                            upload_result: "二维码刷新成功".to_string(),
                                            upload_result_color:"green".to_string(),
                                            qr_url: url.clone().to_string(),
                                            http_root: "".to_string(),
                                            ip_addresses: get_local_ip_addresses(),
                                        }
                                        .render()
                                        .unwrap(),
                                    )
                        ),
            Err(e) => {
                eprintln!("保存配置失败: {}", e);
                Err(StatusCode::BAD_REQUEST)
            }
        }

    }
    pub async fn change_password(auth_session: AuthSession,
                            messages: Messages,  
                            ConnectInfo(addr): ConnectInfo<std::net::SocketAddr>,
                            axum::Form(body): axum::Form<ChangePassword>) -> impl IntoResponse {
        //query sqlite3 database
        //verify the password
        // if match
        // change the password.
        // save to sqlite3
        //return OK;
        // 异步生成新密码哈希
        println!("change pwd");

        let newpwd = body.new_password.clone();
        let password_hash = generate_hash(newpwd.clone());
        let username = &auth_session.user.as_ref().unwrap().username;
        let db = user_init_db().await.expect("fail to init user db");

        if newpwd.clone() != body.confirm_password || newpwd == body.current_password {
            return Html(
                AdminTemplate {
                    messages: messages.into_iter().collect(),
                    username: username,
                    password_change_result: "新密码和确认密码不一致,或者新密码和旧密码相同".to_string(),
                    password_result_color: "red".to_string(),
                }
                .render()
                .unwrap(),
            );  
        } else {
            //get password
            //generate password
            //are they the same
            // if not the same
            let password_hash_result: Option<String> = sqlx::query("SELECT password FROM users WHERE username = ?")
                .bind(username.clone())
                .fetch_optional(&db)
                .await
                .map_err(|e| {
                    eprintln!("数据库错误: {}", e);
                    StatusCode::INTERNAL_SERVER_ERROR
                })
                .unwrap()
                .map(|row| row.get("password")); // 直接从 row 中获取密码字段
            match password_hash_result {
                Some(password_hashx) => {
                    // println!("password hash result {}", password_hashx);
                    if ! verify_password(body.current_password, &password_hashx).is_ok() {
                        return Html(
                            AdminTemplate {
                                messages: messages.into_iter().collect(),
                                username: username,
                                password_change_result: "旧密码不正确".to_string(),
                                password_result_color: "red".to_string(),
                            }
                            .render()
                            .unwrap(),
                        );
                    }
                }
                None => {
                    return Html(
                        AdminTemplate {
                            messages: messages.into_iter().collect(),
                            username: username,
                            password_change_result: "用户名没找到".to_string(),
                            password_result_color: "red".to_string(),
                        }
                        .render()
                        .unwrap(),
                    );
                },
            }
        }
        // 更新数据库中的密码
        let _ = sqlx::query("UPDATE users SET password = ? WHERE username = ?")
            .bind(password_hash)
            .bind(username.clone())
            .execute(&db)
            .await;
        write_log_async( username.to_string(), "INFO".to_string(), addr.to_string(), "修改密码".to_string(),  "密码修改成功".to_string())
            .await.expect("Failed to write log");
        Html(
                AdminTemplate {
                    messages: messages.into_iter().collect(),
                    username: username,
                    password_change_result: "密码修改成功".to_string(),
                    password_result_color: "green".to_string(),
                }
                .render()
                .unwrap(),
        )    
    } 
    pub async fn add_user(ConnectInfo(addr): ConnectInfo<std::net::SocketAddr>,
    // 用 RequestParts 替代单独的 CasbinVals 提取器
                            Extension(casbin_vals): Extension<CasbinVals>,
                            Json(newuser): Json<User>) -> Result<String, StatusCode> {
        // 执行数据库删除操作
        println!("add user {}", newuser.username);
        // 成功提取，直接使用
        println!("当前用户: {}", casbin_vals.subject);
        if newuser.username == "admin" || newuser.username == "administrator" || newuser.username == "root" || newuser.username == "sheisright" || newuser.username == "ferris" {
            println!("DONOT create admin named user ");
            return Err(StatusCode::NOT_FOUND);
        }

        if newuser.id != 0 {
            // 此处改为修改指定用户的信息
            // 增加update user函数
            return update_user_internal(newuser).await;
        }

        if newuser.password.len() < 4 || newuser.password.len() > 160 {
            return Err(StatusCode::NOT_FOUND);
        }
        let password_hash = generate_hash(newuser.password.clone());
        let db = user_init_db().await.expect("fail to init user db");
        let rows_affected = sqlx::query("INSERT INTO users (username, password, email, role, status, accessdir, uploadperm, downloadperm) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
            .bind(&newuser.username)
            .bind(&password_hash)
            .bind(&newuser.email)
            .bind(&newuser.role)
            .bind(&newuser.status)
            .bind(&newuser.accessdir)
            .bind(&newuser.uploadperm)
            .bind(&newuser.downloadperm)
            .execute(&db)
            .await
            .map_err(|e| {
                println!("failed to create user and render 500 {} {} {} {} ", newuser.username, newuser.accessdir, newuser.uploadperm, newuser.downloadperm);
                eprintln!("❌ insert user failed: {e:?}");
                eprintln!("SQL: INSERT INTO users (username, password, email, role, status, accessdir, uploadperm, downloadperm) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
                // 先把值转成 SQLite 字面量
                let sql = format!(
                    r#"INSERT INTO users
                    (username, password, email, role, status, accessdir, uploadperm, downloadperm)
                    VALUES
                    ('{}', '{}', '{}', '{}', '{}', '{}', {}, {})"#,
                    newuser.username,
                    password_hash.replace('\'', "''"),           // 单引号转义
                    newuser.email,
                    newuser.role,
                    newuser.status,
                    newuser.accessdir,
                    newuser.uploadperm,   // bool -> 0/1
                    newuser.downloadperm
                );
                eprintln!("sql:{}", sql);
                StatusCode::INTERNAL_SERVER_ERROR
            });
        if rows_affected?.rows_affected() > 0 {
            let detail = format!("用户{}创建成功", newuser.username);
            write_log_async( 
                "admin".to_string(), "INFO".to_string(), addr.to_string(), "添加用户".to_string(),  detail.to_string())
                .await.expect("Failed to write log");
            println!("add user success");
        } else {
            println!("failed to create user ");
        }

        //add_role_for_user(&newuser.username, &newuser.role).await.unwrap();
        //println!("add role success");

        // 构建数据库路径（使用当前工作目录）
        let db_path = std::env::current_dir().unwrap()
            .join("policy.db");
        
        // 确保目录存在
        if let Some(parent) = db_path.parent() {
            std::fs::create_dir_all(parent).unwrap();
        }

        // 创建数据库连接池
        let db_url = db_path.to_str();

        let pool = SqlitePool::connect(db_url.expect("not-found")).await.unwrap();

        let rows_affected = sqlx::query("INSERT  OR IGNORE INTO casbin_rule (ptype, v0, v1, v2, v3, v4, v5) VALUES ('g', ?, ?, '', '', '', '')")
            .bind(&newuser.username)
            .bind(&newuser.role)
            .execute(&pool)
            .await
            .map_err(|_e| {

                StatusCode::INTERNAL_SERVER_ERROR
            });
        if rows_affected?.rows_affected() > 0 {
            let detail = format!("用户{}创建成功", newuser.username);
            write_log_async( 
                "admin".to_string(), "INFO".to_string(), addr.to_string(), "添加用户".to_string(),  detail.to_string())
                .await.expect("Failed to write log");
            println!("add user for policy success");

            Ok("User add successfully".to_string())
        } else {
            println!("failed to create user policy");
            Err(StatusCode::NOT_FOUND)
        }
    }
    pub async fn update_user(ConnectInfo(addr): ConnectInfo<std::net::SocketAddr>,
                            Json(newuser): Json<User>) -> Result<String, StatusCode> {
        // 执行数据库删除操作
        println!("add user {}", newuser.username);

        if newuser.username == "admin" || newuser.username == "administrator" || newuser.username == "root" || newuser.username == "sheisright" || newuser.username == "ferris" {
            println!("DONOT create admin named user ");
            return Err(StatusCode::NOT_FOUND);
        }

        if newuser.id != 0 {
            // 此处改为修改指定用户的信息
            // 增加update user函数
            return update_user_internal(newuser).await;
        }else {
            return Err(StatusCode::FORBIDDEN); // 禁止使用敏感用户名，返回 403
        }
    }
    /// 修改指定用户信息（通过 id 定位）
    pub async fn update_user_internal(newuser: User) -> Result<String, StatusCode> {
        // 1. 校验用户 ID 有效性（确保 id 是有效的非 0 值）
        if newuser.id == 0 {
            return Err(StatusCode::BAD_REQUEST); // ID 无效，返回 400
        }

        // 2. 校验用户名（禁止使用敏感用户名，与 add_user 保持一致）
        if ["admin", "administrator", "root", "sheisright", "ferris"].contains(&newuser.username.as_str()) {
            return Err(StatusCode::FORBIDDEN); // 禁止使用敏感用户名，返回 403
        }

        // 3. 校验密码长度（与 add_user 保持一致）
        if newuser.password.len() < 4 || newuser.password.len() > 160 {
            return Err(StatusCode::BAD_REQUEST); // 密码长度无效，返回 400
        }

        // 4. 加密密码（与新增用户逻辑一致）
        let password_hash = generate_hash(newuser.password.clone());

        // 5. 初始化数据库连接
        let db = user_init_db()
            .await
            .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; // 数据库初始化失败

        // 6. 执行 SQL 更新操作（通过 id 定位用户）
        let rows_affected = sqlx::query(
            "UPDATE users 
            SET username = ?, password = ?, email = ?, role = ?, status = ? , accessdir = ? , uploadperm = ? , downloadperm = ?
            WHERE id = ?"
        )
        .bind(&newuser.username)
        .bind(&password_hash)
        .bind(&newuser.email)
        .bind(&newuser.role)
        .bind(&newuser.status)
        .bind(&newuser.accessdir)
        .bind(&newuser.uploadperm)
        .bind(&newuser.downloadperm)
        .bind(newuser.id) // 关键：通过 id 定位要修改的用户
        .execute(&db)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; // SQL 执行失败

        // 7. 检查是否有记录被修改
        if rows_affected.rows_affected() > 0 {
            // 记录操作日志（注意：这里需要调用方传递 addr，所以日志参数从 add_user 传入）
            //let detail = format!("用户 {}（ID: {}）修改成功", newuser.username, newuser.id);
            // （日志中的 addr 需从 add_user 函数传入，这里先占位，下方说明）

            println!("update user success: {}, {}, uploadperm {}", newuser.id, newuser.accessdir, newuser.uploadperm);
            Ok("User updated successfully".to_string())
        } else {
            // 未找到对应 id 的用户
            println!("failed to update user: id {} not found", newuser.id);
            Err(StatusCode::NOT_FOUND)
        }
    }

    // Handle POST requests to /save htpp root url
    pub async fn saveroot(auth_session: AuthSession, 
                            messages: Messages, 
                            Json(body): axum::Json<HttpRootConfig>) -> impl IntoResponse {
        // Validate URL
        println!("save http root {}", body.http_root_url);
        let url = body.http_root_url.clone();
        if url.trim().is_empty() {
            return Err(StatusCode::BAD_REQUEST);
        }

        // 保存 URL 到 config.toml
        match save_http_root_url_to_config(&url) {
            Ok(_) => Ok(Html(
                                        FileBrowserTemplate {
                                            messages: messages.into_iter().collect(),
                                            username: &auth_session.user.unwrap().username,
                                            upload_result: "刷新成功".to_string(),
                                            upload_result_color:"green".to_string(),
                                            http_root: crate::util::get_http_root_url(),
                                        }
                                        .render()
                                        .unwrap(),
                                    )
                        ),
            Err(e) => {
                eprintln!("保存配置失败: {}", e);
                Err(StatusCode::BAD_REQUEST)
            }
        }

    }
}


// 保存 URL 到配置文件的函数
fn save_qr_code_url_to_config(url: &str) -> std::io::Result<()> {
    let config_path = get_config_path()?;

    // 创建配置目录（如果不存在）
    if let Some(parent) = config_path.parent() {
        fs::create_dir_all(parent)?;
    }
    println!("save to {:?}", config_path);   
    // 创建配置结构
    let config = QRConfig {
        qr_code_url: url.to_string(),
    };
    
    // 序列化为 TOML 格式
    let toml_data = toml::to_string(&config).map_err(|e| {
        std::io::Error::new(std::io::ErrorKind::Other, format!("序列化失败: {}", e))
    })?;
    
    // 写入文件
    let mut file = File::create(config_path)?;
    file.write_all(toml_data.as_bytes())?;
    
    Ok(())
}

// 获取配置文件路径
fn get_config_path() -> std::io::Result<PathBuf> {
    let mut config_dir = dirs::config_dir()
        .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "无法获取配置目录"))?;
    config_dir.push("sheisright");
    config_dir.push("qr.toml");
    Ok(config_dir)
}

#[derive(Debug, Clone, Deserialize)]
pub struct ChangePassword {
    pub current_password: String,
    pub new_password: String,
    pub confirm_password: String,
}
#[derive(Serialize)]
pub struct DeleteUserQuery {
    #[serde(rename = "type")]
    user_id: String, // "directory" or "file"
}
pub mod delete {
    use super::*;
    // Handle DELETE requests to /delete_user
    pub async fn delete_user(ConnectInfo(addr): ConnectInfo<std::net::SocketAddr>,
                                id: String) -> Result<String, StatusCode> {
        // 执行数据库删除操作
        println!("delete user {id}");
        if id == "0" || id == "1" {
            return Err(StatusCode::NOT_FOUND);
        }
        let db = user_init_db().await.expect("fail to init user db");
        let rows_affected = sqlx::query("DELETE FROM users WHERE id = ?")
            .bind(&id)
            .execute(&db)
            .await
            .map_err(|_e| {

                StatusCode::INTERNAL_SERVER_ERROR
            });
        if rows_affected?.rows_affected() > 0 {
            let detail = format!("用户id{}删除成功", id);
            write_log_async( 
                "admin".to_string(), "INFO".to_string(), addr.to_string(), "删除用户".to_string(),  detail.to_string())
                .await.expect("Failed to write log");
            println!("delete user {id} success");
            Ok("User deleted successfully".to_string())
        } else {
            println!("not found user {id}");
            Err(StatusCode::NOT_FOUND)
        }

    }
}

// 使用getifaddrs获取本地所有非环回IP地址
pub fn get_local_ip_addresses() -> Vec<String> {
    let mut ips = HashSet::new();

    match getifaddrs() {
        Ok(interfaces) => {
            println!("所有非环回IP地址:");
            for iface in interfaces {
                let addr = iface.address;
                
                match addr {
                    IpAddr::V4(ipv4) => {
                        // 过滤回环地址
                        if !ipv4.is_loopback() {
                            let ip_str = ipv4.to_string();
                            println!("IPv4: {} (接口: {})", ipv4, iface.name);
                            ips.insert(ip_str);
                        }
                    }
                    IpAddr::V6(ipv6) => {
                        // 过滤回环地址
                        if !ipv6.is_loopback() {
                            let ip_str = ipv6.to_string();
                            ips.insert(ip_str);
                            println!("IPv6: {} (接口: {})", ipv6, iface.name);
                        }
                    }
                }
            }
        }
        Err(e) => {
            eprintln!("获取网络接口失败: {}", e);
        }
    }
    
    // 转换为有序向量
    let mut ip_vec: Vec<String> = ips.into_iter().collect();
    ip_vec.sort();
    
    ip_vec
}